package au.com.handsunited.dao.hibernate;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Query;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import au.com.handsunited.dao.OrganisationDAO;
import au.com.handsunited.model.Organisation;

/**
 *
 * @author arunda
 */
public class OrganisationDAOHibernate extends EntityDAOHibernate implements OrganisationDAO {


	private static Logger logger = LoggerFactory.getLogger(OrganisationDAOHibernate.class);

	/**
	 * @see au.com.handsunited.dao.impl.OrganisationDAO#getOrganisation(java.lang.Long)
	 */
	public Organisation getOrganisation(Long id) {
		return (Organisation) getEntity(id, Organisation.class);
	}

	/**
	 * @see au.com.handsunited.dao.impl.OrganisationDAO#getAllOrganisations()
	 */
	public List<Organisation> getAllOrganisations() {
		return getHibernateTemplate().find("from Organisation");
	}

	/**
	 * @see au.com.handsunited.dao.impl.OrganisationDAO#deleteOrganisation(java.lang.Long)
	 */
	public boolean deleteOrganisation(Organisation organisation) {
		getHibernateTemplate().delete(organisation);
		return true;
	}

	/**
	 * @see au.com.handsunited.dao.impl.OrganisationDAO#createOrganisation(au.com.handsunited.model.old.Organisation)
	 */
	public Organisation createOrganisation(Organisation organisation) {
		return (Organisation) createEntity(organisation);
	}


	/**
	 * @see au.com.handsunited.dao.impl.OrganisationDAO#updateOrganisation(au.com.handsunited.model.Organisation)
	 */
	@Override
	public Organisation updateOrganisation(Organisation organisation) {
		return (Organisation) updateEntity(organisation);
	}

	/**
	 * Search fields are name, keywords, suburb, city, state, service categories
	 * @see au.com.handsunited.dao.OrganisationDAO#searchForOrganisationsByCriteria(au.com.handsunited.model.Organisation)
	 */
	@Override
	public List<Organisation> searchForOrganisationsByCriteria(
			Organisation organisationCriteria) {


		Criteria criteria = getSession().createCriteria(Organisation.class);

		if (StringUtils.isNotBlank(organisationCriteria.getName())) {
			criteria.add(Restrictions.ilike(
					"name",
					"%"+organisationCriteria.getName()+"%")
			);
		}

		if (StringUtils.isNotBlank(organisationCriteria.getLocation().getSuburb())) {
			criteria.add(Restrictions.ilike(
					"location.suburb",
					organisationCriteria.getLocation().getSuburb(),
					MatchMode.ANYWHERE)
			);
		}

		if (StringUtils.isNotBlank(organisationCriteria.getLocation().getCity())) {
			criteria.add(Restrictions.ilike(
					"location.city",
					organisationCriteria.getLocation().getCity(),
					MatchMode.ANYWHERE)
			);
		}

		if (StringUtils.isNotBlank(organisationCriteria.getLocation().getState())) {
			criteria.add(Restrictions.ilike(
					"location.state",
					organisationCriteria.getLocation().getState(),
					MatchMode.ANYWHERE)
			);
		}

		List<Organisation> organisations = criteria.list();
		return organisations;
	}

	/**
	 * @see au.com.handsunited.dao.OrganisationDAO#searchForOrganisationsByKeywords(java.lang.String)
	 */
	@Override
	public List<Organisation> searchForOrganisationsByKeywords(String keywords) {
		FullTextSession fullTextSession = Search.createFullTextSession(getSession());

		MultiFieldQueryParser parser = new MultiFieldQueryParser(
				new String[]{"name", "summary", "description"}, new StandardAnalyzer());
		Query query = null;

		try {
			query = parser.parse(keywords);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(query, Organisation.class);
		List<Organisation> organisations = hibQuery.list();

		return organisations;
	}


}
